<?php

namespace App\Services\Message;

use App\Exceptions\MessageException;
use App\Lib\Util\ErrorCode;

class ApiAuthService
{
    const REQUEST_TIMEOUT = 600; //请求过期时间10分钟
    const TEST_SECRET_ID = 10009527; //测试环境测试用，配置在secret中

    /**
     * 测试环境发请求（自用)
     * @param $params
     * @return array
     */
    public function signForTest(array $params): array
    {
        $params['secret_id'] = self::TEST_SECRET_ID;
        $params['timestamp'] = time();
        $params['sign'] = $this->sign(self::TEST_SECRET_ID, $params);

        return $params;
    }

    /**
     * 验证签名
     * @param array $params
     * @return void
     * @throw App\Exceptions\MessageException
     */
    public function verify(array $params,array $header): void
    {
        if (empty($params['secret_id'])) {
            throw new MessageException('请提供secret_id', ErrorCode::MESSAGE_REQUEST_UNAUTHORIZED);
        }

        if (empty($params['timestamp']) || time() - $params['timestamp'] > self::REQUEST_TIMEOUT) {
            throw new MessageException('请求已过期', ErrorCode::MESSAGE_REQUEST_UNAUTHORIZED);
        }

        if (empty($params['sign'])) {
            throw new MessageException('缺少签名', ErrorCode::MESSAGE_REQUEST_UNAUTHORIZED);
        }

        $sign = $params['sign'];
        unset($params['sign']);
        if ($sign != $this->sign($params['secret_id'], $params)) {
            throw new MessageException('签名验证不通过', ErrorCode::MESSAGE_REQUEST_UNAUTHORIZED);
        }
    }

    /**
     * 对参数签名
     * @param int $secretId
     * @param array $params
     * @return string
     */
    protected function sign(int $secretId, array $params): string
    {
//      p($params);exit;
      $config = config('secret');
      if (empty($config[$secretId])) {
            throw new MessageException('无效的secret_id', ErrorCode::MESSAGE_REQUEST_UNAUTHORIZED);
        }
        $signString = $config[$secretId];

        $params['secret_id'] = $secretId;
        unset($params['sign']);
        ksort($params);
        foreach ($params as $key => $value) {
            $signString .= $key;
//            $signString .= $value;
        }
      return md5($signString);
    }
}
